package j.framework.base.service.impl;

import j.framework.base.service.ApplicationService;
import j.framework.core.*;
import j.util.Guid;
import j.util.New;
import j.util.StringUtils;
import j.util.jdbc.JdbcTemplate;
import j.util.jdbc.JdbcUtils;
import j.util.jdbc.ResultSetHandler;
import j.util.jdbc.RowMapper;
import j.util.pkgenerator.PG;
import org.springframework.beans.factory.annotation.Autowired;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;

/**
 * User: jason
 * Date: 2014/11/6 13:59
 */
public class ApplicationServiceImpl implements ApplicationService {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Override
    public String getSetting(String key) {
        return (String)jdbcTemplate.queryForObject("select ss_value from sys_setting where ss_key=?",key);
    }

    @Override
    public Function getFunction(String fid) {
        return jdbcTemplate.queryForDomain("SELECT moduleID,moduleName,isJsp,URL,iconURL,displayOrder,parentModuleID FROM bas_Module WHERE moduleID=?",new RowMapper<Function>() {
            @Override
            public Function mapRow(ResultSet rs, int rowNum) throws SQLException {
                Function f = new Function();
                f.setFunctionId(rs.getString("moduleID"));
                f.setName(rs.getString("moduleName"));
                f.setJsp(rs.getBoolean("isJsp"));
                f.setUrl(rs.getString("URL"));
                f.setFunctionPid(rs.getString("parentModuleID"));
                f.setIcon(rs.getString("iconURL"));
                f.setDisplayOrder(JdbcUtils.getDouble(rs,"displayOrder"));
                return f;
            }
        },fid);
    }

    @Override
    public List<DictItem> getDictItems(String dictId) {
        return jdbcTemplate.queryForList("SELECT * FROM bas_DictItems WHERE dictID=? ORDER BY displayOrder",
                dictItemRowMapper, dictId);
    }

    @Override
    public Map<String, DictItem> getAllDictItems(String dictId) {
        final Map<String,DictItem> map = New.map();
        jdbcTemplate.queryForList("SELECT * FROM bas_DictItems WHERE dictID=?",
                new ResultSetHandler() {
                    @Override
                    public void doResultSet(ResultSet rs) throws SQLException {
                        DictItem item = getDictItemFromResultSet(rs);
                        map.put(item.getCode(),item);
                    }
                },dictId);
        return map;
    }

    @Override
    public Map<String, DictItem> getAllDictItems() {
        final Map<String,DictItem> map = New.map();
        jdbcTemplate.queryForList("SELECT * FROM bas_DictItems",
                new ResultSetHandler() {
                    @Override
                    public void doResultSet(ResultSet rs) throws SQLException {
                        DictItem item = getDictItemFromResultSet(rs);
                        map.put(item.getCode(),item);
                    }
                });
        return map;
    }

    @Override
    public List<Dict> getDictionaries() {
        return jdbcTemplate.queryForList("SELECT * FROM bas_Dictionary", dictRowMapper);
    }

    @Override
    public WebRequestConfiguration getWebRequestConfiguration(String requestId) {
        return jdbcTemplate.queryForDomain("select *,(select moduleName from bas_Module where moduleID=r.function_id) as function_name,(select authName from bas_ModuleAuth where moduleAuthID=r.action_id) as action_name from sys_web_request r where request_id=?",
                webRequestRowMapper,requestId);
    }

    @Override
    public List<Action> getFunctionActions(String fid) {
        return jdbcTemplate.queryForList("select * from bas_ModuleAuth where moduleID=?",new RowMapper<Action>() {
            @Override
            public Action mapRow(ResultSet rs, int rowNum) throws SQLException {
                Action a = new Action();
                a.setActionId(rs.getString("moduleAuthID"));
                a.setName(rs.getString("authName"));
                return a;
            }
        },fid);
    }

    @Override
    public Map<String, DictItem> getAllUsers() {
        final Map<String,DictItem> map = New.map();
        jdbcTemplate.queryForList("SELECT userID,userName FROM bas_User",
                new ResultSetHandler() {
                    @Override
                    public void doResultSet(ResultSet rs) throws SQLException {
                        DictItem item = new DictItem();
                        item.setCode(rs.getString("userID"));
                        item.setName(rs.getString("userName"));
                        map.put(item.getCode(),item);
                    }
                });
        return map;
    }

    @Override
    public Map<String, DictItem> getAllDepts() {
        final Map<String,DictItem> map = New.map();
        jdbcTemplate.queryForList("SELECT orgID,orgName FROM bas_Organization",
                new ResultSetHandler() {
                    @Override
                    public void doResultSet(ResultSet rs) throws SQLException {
                        DictItem item = new DictItem();
                        item.setCode(rs.getString("orgID"));
                        item.setName(rs.getString("orgName"));
                        map.put(item.getCode(),item);
                    }
                });
        return map;
    }

    /**
     * 记录系统日志
     *
     * @param log
     */
    @Override
    public void log(SysLog log) {
        log(jdbcTemplate,log);
    }

    /**
     * 记录系统日志
     *
     * @param jt  JdbcTemplate
     * @param log
     */
    @Override
    public void log(JdbcTemplate jt, SysLog log) {
        Map<String,Object> mapData = New.map();
        mapData.put("logID",log.getLogId());
        mapData.put("moduleID",log.getModuleId());
        mapData.put("moduleAuthID",log.getModuleAuthId());
        mapData.put("businessType",log.getBusinessType());
        mapData.put("operateType",log.getOperateType());
        mapData.put("className",log.getClassName());
        mapData.put("methodName",log.getMethodName());
        mapData.put("parms",log.getParamsInfo());
        mapData.put("returnValue",log.getReturnValue());
        mapData.put("exception",log.getException());
        mapData.put("logs",log.getLogContent());
        mapData.put("operateUserID",log.getOperateUserId());
        mapData.put("operateTime",log.getOperateTime());
        mapData.put("userIP",log.getUserIP());
        jt.executeInsert("bas_SysLogs",mapData);
    }

    @Override
    public void log(JdbcTemplate jt, List<SysLog> logs) {
        String sql = "INSERT INTO bas_SysLogs(logID, moduleID, moduleAuthID, businessType, operateType, className, methodName, parms, returnValue, exception, logs, batch,operateUserID, operateTime,userIP)VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
        List<Object[]> argsList=New.list();
        Object[] args;
        String batch = Guid.newGuid();
        for(SysLog log : logs){
            args = new Object[14];
            args[0] = PG.getNext("LOG");
            args[1] = log.getModuleId();
            args[2] = log.getModuleAuthId();
            args[3] = log.getBusinessType();
            args[4] = log.getOperateType();
            args[5] = log.getClassName();
            args[6] = log.getMethodName();
            args[7] = log.getParamsInfo();
            args[8] = log.getReturnValue();
            args[9] = log.getException();
            args[10] = log.getLogContent();
            args[11] = batch;
            args[12] = log.getOperateUserId();
            args[13] = log.getOperateTime();
            args[14] = log.getUserIP();
            argsList.add(args);
        }
        jt.executeBatch(sql,argsList);
    }

    private static final RowMapper<Dict> dictRowMapper = new RowMapper<Dict>() {
        public Dict mapRow(ResultSet rs, int rowNum) throws SQLException {
            Dict d = new Dict();
            d.setCode(rs.getString("dictID"));
            d.setName(rs.getString("dicName"));
            return d;
        }
    };
    public static final RowMapper<WebRequestConfiguration> webRequestRowMapper = new RowMapper<WebRequestConfiguration>() {
        public WebRequestConfiguration mapRow(ResultSet rs, int rowNum) throws SQLException {
            WebRequestConfiguration d = new WebRequestConfiguration();
            d.setRequestId(rs.getString("request_id"));
            d.setRequestName(rs.getString("name"));
            d.setFunctionId(rs.getString("function_id"));
            d.setFunctionName(rs.getString("function_name"));
            d.setActionId(rs.getString("action_id"));
            d.setActionName(rs.getString("action_name"));
            d.setCheckFunctionPrivilege(rs.getBoolean("check_function_privilege"));
            d.setCheckActionPrivilege(rs.getBoolean("check_action_privilege"));
            d.setRequestType(rs.getString("request_type"));
            d.setResponseType(rs.getString("response_type"));
            d.setUrl(rs.getString("url"));
            d.setUsedGeneralService(rs.getBoolean("used_general_service"));
            d.setLogSupported(rs.getBoolean("log_supported"));
            if(d.isUsedGeneralService()){
                d.setGeneralAction(rs.getString("general_action"));
                d.setEntityPkGenerateKey(rs.getString("pk_tbl_key"));
                d.setEntityClassName(rs.getString("entity_class_name"));
                d.setEntityTrigger(rs.getString("entity_trigger"));
            }else{
                d.setBeanClassName(rs.getString("bean_class_name"));
                d.setBeanClassMethodName(rs.getString("bean_class_method_name"));
            }
            return d;
        }
    };

    private static DictItem getDictItemFromResultSet(ResultSet rs)throws SQLException{
        DictItem item = new DictItem();
        item.setValue(rs.getString("itemCode"));
        item.setName(rs.getString("dictID"));
        if(StringUtils.isNotEmpty(item.getValue())){
            item.setCode(item.getName()+"_"+item.getValue());
        }else{
            item.setCode(item.getName()+"_"+rs.getString("dictItemID"));
        }
//        item.setValue(rs.getString("dictItemID"));
//        item.setCode(rs.getString("itemCode"));
        item.setName(rs.getString("itemName"));
        item.setDisabled(rs.getBoolean("isDisabled"));
        return item;
    }

    private static final RowMapper<DictItem> dictItemRowMapper = new RowMapper<DictItem>() {
        public DictItem mapRow(ResultSet rs, int rowNum) throws SQLException {
            return getDictItemFromResultSet(rs);
        }
    };
}
